package org.burning.crm.settings.web.controller;

import org.burning.crm.commons.constants.Constant;
import org.burning.crm.commons.domain.ReturnObject;
import org.burning.crm.commons.utils.DateUtils;
import org.burning.crm.commons.utils.SendMailUtils;
import org.burning.crm.commons.utils.UUIDUtils;
import org.burning.crm.settings.service.SmsService;
import org.burning.crm.settings.domain.User;
import org.burning.crm.settings.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

@Controller
public class UserController {
    @Autowired
    private UserService userService;


    @Autowired
    private SmsService smsService;

    private static final long CODE_EXPIRE_TIME = 5 * 60 * 1000; // 5分钟


    /*
        url 要和 controller方法处理请求之后，响应信息返回的页面的目录保持一致
     */
    @RequestMapping("/settings/qx/user/toLogin.do")
    public String toLogin() {
        //请求转发到登录页面
        return "settings/qx/user/login";
        // 请求转发到登录页面
    }

    @RequestMapping("/settings/qx/user/register.do")
    public String register() {
        //请求转发到注册页面
        return "settings/qx/user/register";
    }

    /**
     * 用户登录
     * @param loginAct  账号
     * @param loginPwd  密码
     * @param isRemPwd  记住我
     * @param request
     * @param session
     * @param response
     * @return
     */
    @RequestMapping("/settings/qx/user/login.do")
    public @ResponseBody Object login(String loginAct, String loginPwd, String isRemPwd, HttpServletRequest request, HttpSession session, HttpServletResponse response){
        //封装参数
        Map<String, Object> map = new HashMap<>();
        map.put("loginAct",loginAct);
        map.put("loginPwd",loginPwd);
        //调用service层方法，查询用户
        User user = userService.queryUserByLoginActAndPwd(map);
        //根据查询结果，生成响应信息
        ReturnObject returnObject = new ReturnObject();
        if (user == null) {
            //登录失败，用户名或者密码错误
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("用户名或者密码错误");
        } else {//进一步判断账号是否合法
            if (DateUtils.formatDateTime(new Date()).compareTo(user.getExpireTime()) > 0) {
                //登录失败，账号已过期
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
                returnObject.setMessage("账号已过期");
            } else if ("0".equals(user.getLockState())){
                //登录失败，账号已锁定
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
                returnObject.setMessage("账号被锁定");
            } else if (!user.getAllowIps().contains(request.getRemoteAddr())) {
                //登录失败，ip受限
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
                returnObject.setMessage("ip受限");
            } else {
                //登录成功
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);

                //把user放到session中
                session.setAttribute(Constant.SESSION_USER,user);

                //如果需要记住密码，则往外写cookie
                if ("true".equals(isRemPwd)) {
                    Cookie cookie1 = new Cookie("loginAct", user.getLoginAct());
                    //设置cookie寿命10天
                    cookie1.setMaxAge(10*24*60*60);
                    response.addCookie(cookie1);
                    Cookie cookie2 = new Cookie("loginPwd", user.getLoginPwd());
                    cookie2.setMaxAge(10*24*60*60);
                    response.addCookie(cookie2);
                } else {
                    //把没有过期的cookie删除
                    Cookie cookie1 = new Cookie("loginAct", null);
                    cookie1.setMaxAge(0);
                    response.addCookie(cookie1);
                    Cookie cookie2 = new Cookie("loginPwd", null);
                    cookie2.setMaxAge(0);
                    response.addCookie(cookie2);
                }
            }
        }
        return returnObject;
    }

    /**
     * 退出登录
     * @param response
     * @param session
     * @return
     */
    @RequestMapping("/settings/qx/user/logout.do")
    public String logout(HttpServletResponse response,HttpSession session) {
        //清空cookie
        Cookie cookie1 = new Cookie("loginAct", null);
        cookie1.setMaxAge(0);
        response.addCookie(cookie1);
        Cookie cookie2 = new Cookie("loginPwd", null);
        cookie2.setMaxAge(0);
        response.addCookie(cookie2);

        //销毁session
        session.invalidate();

        //重定向到登录页面(不需要视图解析器)
        return "redirect:/";
    }

    /**
     * 点击获取验证码，发送邮箱
     * @param email 登录者的邮箱
     * @return
     */
    //@PostMapping("/settings/qx/user/sendEmail") 为什么用/settings/qx/user/前缀的路径不能调用啊啊qwq
    @RequestMapping("/sendEmail")
    public @ResponseBody
    Object sendEmail(String email, HttpServletRequest request, HttpSession session) {
        ReturnObject returnObject = new ReturnObject();
        // 随机生成4位验证码
        Random rd = new Random();
        // 实例化一个一个string数组
        String[] strings = new String[] {
                "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "q", "w", "e", "r", "t",
                "y", "u", "i", "o", "p", "a", "s", "d", "f", "g", "h", "j", "k", "l", "z", "x", "c", "v", "b", "n", "m",
                "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "A", "S", "D", "F", "G", "H", "J", "K", "L", "Z", "X",
                "C", "V", "B", "N", "M" };
        // 定义一个变量接受，0~9 24个英文字母大小写 随机四个
        String authCode = "";
        for (int i = 0; i < 4; i++) {
            int sj = rd.nextInt(strings.length);
            authCode += strings[sj];
        }

        // 先查询数据库的邮箱对应的用户，有就执行登录验证逻辑
        int userEmail = userService.queryUserByLoginEmail(email);
        if (userEmail > 0) {
            // 发送邮箱，除非配置出问题都能发送
            boolean sendSuccess = SendMailUtils.sendMail(email, authCode, session);
            if (sendSuccess) {
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);
                returnObject.setMessage("验证码发送成功");
            } else {
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
                returnObject.setMessage("验证码发送失败，请稍后重试");
            }
        }
        return returnObject;
    }


    /**
     * 点击登录时，校验验证码一致性
     * @param email     登录者邮箱
     * @param _authCode 登录者输入的验证码
     * @param request   请求对象
     * @param response  响应对象
     * @param session   会话
     * @return 响应结果
     */
    @RequestMapping("/loginByEmail")
    @ResponseBody
    public Object loginByEmail(String email, String _authCode, HttpServletRequest request, HttpSession session, HttpServletResponse response) {
        ReturnObject returnObject = new ReturnObject();

        // 在前端已经验证了邮箱和密码不能为空

        String authCode = (String) session.getAttribute("authCode");

        // 忽略大小写对比验证码
        if (!_authCode.equalsIgnoreCase(authCode)) {
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("验证码错误");
            return returnObject;
        }

        // 验证码一致，继续往下处理

        // 清除已使用的验证码
        session.removeAttribute("authCode");

        // 根据邮箱获取登录者
        User user = userService.getUserByEmail(email);
        System.out.println(user);

        // 登录失败，账号已过期
        if (DateUtils.formatDateTime(new Date()).compareTo(user.getExpireTime()) > 0) {
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("账号已过期");
        } else if ("0".equals(user.getLockState())){
            // 登录失败，账号已锁定
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("账号被锁定");
        }
//        else if (!user.getAllowIps().contains(request.getRemoteAddr())) {
//            // 登录失败，ip受限
//            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
//            returnObject.setMessage("ip受限");
//        }
        else {
            // 登录成功
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);
            returnObject.setMessage("success");
            session.setAttribute(Constant.SESSION_USER,user);
        }
        return returnObject;
    }


    /**
     * 发送验证码接口
     * 该方法用于接收一个电话号码参数，生成一个6位数字的验证码，并将其发送到指定的电话号码
     * 验证码在发送成功后会被保存在HTTP会话中，以供后续验证使用
     *
     * @param phone 接收验证码的电话号码
     * @param session 用于存储验证码信息的HTTP会话
     * @return 返回一个对象，表示验证码发送的结果
     */
    @PostMapping("/sendCode")
    @ResponseBody
    public Object sendMessage(String phone, HttpSession session) {
        ReturnObject returnObject = new ReturnObject();
        // 验证手机号格式
        if (!phone.matches("^1[3-9]\\d{9}$")) {
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("请输入正确的手机号");
            return returnObject;
        }


        if (userService.queryUserByLoginPhone(phone) == null) {
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("手机号未注册");
            return returnObject;
        }

        // 检查发送频率（60秒内只能发送一次）
        Long lastSendTime = (Long) session.getAttribute("smsCodeTime_" + phone);
        if (lastSendTime != null && System.currentTimeMillis() - lastSendTime < 60 * 1000) {
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("验证码发送太频繁，请稍后再试");
            return returnObject;
        }

        // 生成6位随机验证码
        String code = String.format("%06d", new Random().nextInt(999999));

        // 调用短信服务发送验证码
        boolean isSuccess = smsService.sendVerificationCode(phone, code);

        if (isSuccess) {
            // 保存验证码信息到session
            session.setAttribute("smsCode_" + phone, code);
            session.setAttribute("smsCodeTime_" + phone, System.currentTimeMillis());

            returnObject.setMessage("验证码发送成功");
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);
            return returnObject;
        } else {
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("验证码发送失败，请稍后重试");
            return returnObject;
        }
    }

    /**
     * 短信验证码登录
     */
    @PostMapping("/loginByPhone")
    @ResponseBody
    public ReturnObject loginByPhone(@RequestParam String phone,
                                     @RequestParam String code,
                                     HttpServletRequest request,
                                     HttpSession session) {
        ReturnObject returnObject = new ReturnObject();

        // 从session获取验证码信息
        String sessionCode = (String) session.getAttribute("smsCode_" + phone);
        Long sendTime = (Long) session.getAttribute("smsCodeTime_" + phone);

        // 验证码检查
        if (sessionCode == null || sendTime == null) {
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("验证码不存在或已过期");
            return returnObject;
        }

        // 验证码是否过期（5分钟）
        if (System.currentTimeMillis() - sendTime > CODE_EXPIRE_TIME) {
            session.removeAttribute("smsCode_" + phone);
            session.removeAttribute("smsCodeTime_" + phone);
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("验证码已过期");
            return returnObject;
        }

        // 验证码是否正确
        if (!sessionCode.equals(code)) {
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("验证码错误");
            return returnObject;
        }

        // 验证通过，清除验证码
        session.removeAttribute("smsCode_" + phone);
        session.removeAttribute("smsCodeTime_" + phone);

        // 查询用户信息
        User user = userService.queryUserByLoginPhone(phone);
        if (user == null) {
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("用户不存在");
            return returnObject;
        }

        // 检查账号状态
        if (DateUtils.formatDateTime(new Date()).compareTo(user.getExpireTime()) > 0) {
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("账号已过期");
        } else {
            // 登录成功，设置用户会话
            session.setAttribute(Constant.SESSION_USER, user);
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);
            returnObject.setMessage("登录成功");
        }

        return returnObject;
    }


    @GetMapping("/checkCodeStatus")
    @ResponseBody
    public ReturnObject checkCodeStatus(@RequestParam String phone, HttpSession session) {
        ReturnObject returnObject = new ReturnObject();

        Long sendTime = (Long) session.getAttribute("smsCodeTime_" + phone);
        if (sendTime != null) {
            long elapsed = System.currentTimeMillis() - sendTime;
            long remaining = Math.max(0, 60 - (elapsed / 1000));

            returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);
            returnObject.setRetData(remaining);

        } else {
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
        }

        return returnObject;
    }

    /**
     * 点击获取验证码，发送邮箱
     * @param email 登录者的邮箱
     * @return
     */
    //@PostMapping("/settings/qx/user/sendEmail") 为什么用/settings/qx/user/前缀的路径不能调用啊啊qwq
    @RequestMapping("/sendEmailByRegister")
    @ResponseBody
    public Object sendEmailByRegister(String email, HttpServletRequest request, HttpSession session) {
        ReturnObject returnObject = new ReturnObject();
        // 随机生成4位验证码
        Random rd = new Random();
        // 实例化一个一个string数组
        String[] strings = new String[] {
                "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "q", "w", "e", "r", "t",
                "y", "u", "i", "o", "p", "a", "s", "d", "f", "g", "h", "j", "k", "l", "z", "x", "c", "v", "b", "n", "m",
                "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "A", "S", "D", "F", "G", "H", "J", "K", "L", "Z", "X",
                "C", "V", "B", "N", "M" };
        // 定义一个变量接受，0~9 24个英文字母大小写 随机四个
        String authCode = "";
        for (int i = 0; i < 4; i++) {
            int sj = rd.nextInt(strings.length);
            authCode += strings[sj];
        }

        // 先查询数据库的邮箱对应的用户，有就执行登录验证逻辑
        int userEmail = userService.queryUserByLoginEmail(email);
        if (userEmail > 0) {
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("该邮箱已被用户注册");
        } else {
            // 发送邮箱，除非配置出问题都能发送
            boolean sendSuccess = SendMailUtils.sendMail(email, authCode, session);
            if (sendSuccess) {
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);
                returnObject.setMessage("(注册)验证码发送成功");
            } else {
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
                returnObject.setMessage("发送失败");
            }
        }
        return returnObject;
    }

    /**
     * 注册
     * 点击注册按钮时调用。整体逻辑：
     * 用户输入好信息，点击发送验证码
     * @param name      昵称
     * @param loginAct  账号
     * @param loginPwd  密码
     * @param email     邮箱
     * @param authCode  前台的验证码
     * @param session
     * @return
     */
    @PostMapping("/user/register")
    @ResponseBody
    public Object userRegister(String name, String loginAct, String loginPwd, String email, String authCode,HttpSession session) {
        ReturnObject returnObject = new ReturnObject();

        // 检查用户名是否存在
        User user = userService.queryUserByLoginAct(loginAct);
        System.out.println(user);

        if (user == null) {
            // 未被注册，验证信息
            String authCode_session = (String) session.getAttribute("authCode");
            System.out.println(authCode);
            System.out.println(authCode_session);
            if (authCode.equalsIgnoreCase(authCode_session)) {
                User newUser = new User();
                System.out.println("newUser = " + newUser);
                newUser.setId(UUIDUtils.getUUID());
                newUser.setLoginAct(loginAct);
                newUser.setLoginPwd(loginPwd);
                newUser.setEmail(email);
                newUser.setName(name);
                newUser.setExpireTime("2044-11-02 23:50:55");
                newUser.setLockState("1");
                newUser.setDeptno("A001");
                newUser.setAllowIps("192.168.1.1,0:0:0:0:0:0:0:1");
                newUser.setCreatetime(DateUtils.formatDateTime(new Date()).toString());
                newUser.setCreateBy("admin");
                newUser.setEditTime(DateUtils.formatDateTime(new Date()).toString());
                newUser.setEditBy("admin");
                System.out.println("添加数据的user：" + newUser);
                userService.addUser(newUser);

                returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);
                returnObject.setRetData(newUser);
                returnObject.setMessage("注册成功");
            } else {
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
                returnObject.setMessage("验证码错误");
            }
        } else {
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("该用户名已存在");
        }

        return returnObject;
    }


}
